package com.hx78.mongo.uni;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import org.springframework.data.mongodb.core.query.*;

import java.util.*;

/**
 * @author linming
 */
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class QueryForMongo {

    private Map<String, Criteria> criteria = new LinkedHashMap<>();

    private SortForMongo sort;

    private long skip;

    private int limit;

    private String hint;

    private Meta meta;

    private Collation collation;

//    /**
//     * Static factory method to create a {@link Query} using the provided {@link CriteriaDefinition}.
//     *
//     * @param criteriaDefinition must not be {@literal null}.
//     * @return new instance of {@link Query}.
//     * @since 1.6
//     */
//    public static QueryForMongo query(Criteria criteriaDefinition) {
//        return new QueryForMongo(criteriaDefinition);
//    }
//
//    public QueryForMongo() {}
//
//    /**
//     * Creates a new {@link Query} using the given {@link CriteriaDefinition}.
//     *
//     * @param criteriaDefinition must not be {@literal null}.
//     * @since 1.6
//     */
//    public QueryForMongo(Criteria criteriaDefinition) {
//        addCriteria(criteriaDefinition);
//    }

//    public QueryForMongo addCriteria(Criteria criteriaDefinition) {
//
//        Assert.notNull(criteriaDefinition, "CriteriaDefinition must not be null!");
//
//        CriteriaDefinition existing = this.criteria.get(criteriaDefinition.getKey());
//        String key = criteriaDefinition.getKey();
//
//        if (existing == null) {
//            this.criteria.put(key, criteriaDefinition);
//        } else {
//            throw new InvalidMongoDbApiUsageException(
//                    String.format("Due to limitations of the com.mongodb.BasicDocument, you can't add a second '%s' criteria. "
//                            + "Query already contains '%s'", key, serializeToJsonSafely(existing.getCriteriaObject())));
//        }
//
//        return this;
//    }
//
//
//
//    public QueryForMongo skip(long skip) {
//        this.skip = skip;
//        return this;
//    }
//
//
//    public QueryForMongo limit(int limit) {
//        this.limit = limit;
//        return this;
//    }
//
//
//    public QueryForMongo withHint(String hint) {
//
//        Assert.hasText(hint, "Hint must not be empty or null!");
//        this.hint = hint;
//        return this;
//    }
//
//
//    public QueryForMongo withHint(Document hint) {
//
//        Assert.notNull(hint, "Hint must not be null!");
//        this.hint = hint.toJson();
//        return this;
//    }
//
//
//    public QueryForMongo with(Pageable pageable) {
//
//        if (pageable.isUnpaged()) {
//            return this;
//        }
//
//        this.limit = pageable.getPageSize();
//        this.skip = pageable.getOffset();
//
//        return with(pageable.getSort());
//    }
//
//    public QueryForMongo with(Sort sort) {
//
//        Assert.notNull(sort, "Sort must not be null!");
//
//        if (sort.isUnsorted()) {
//            return this;
//        }
//
//        sort.stream().filter(Sort.Order::isIgnoreCase).findFirst().ifPresent(it -> {
//
//            throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case! "
//                    + "MongoDB does not support sorting ignoring case currently!", it.getProperty()));
//        });
//
//        this.sort = this.sort.and(sort);
//
//        return this;
//    }
//
//
//    public boolean isSorted() {
//        return sort.isSorted();
//    }
//
//
//    public long getSkip() {
//        return this.skip;
//    }
//
//    public int getLimit() {
//        return this.limit;
//    }
//
//
//    @Nullable
//    public String getHint() {
//        return hint;
//    }
//
//
//    public QueryForMongo maxTimeMsec(long maxTimeMsec) {
//
//        meta.setMaxTimeMsec(maxTimeMsec);
//        return this;
//    }
//
//
//    public QueryForMongo maxTime(long timeout, TimeUnit timeUnit) {
//
//        meta.setMaxTime(timeout, timeUnit);
//        return this;
//    }
//
//    public QueryForMongo maxTime(Duration timeout) {
//        meta.setMaxTime(timeout);
//        return this;
//    }
//
//
//    public QueryForMongo comment(String comment) {
//
//        meta.setComment(comment);
//        return this;
//    }
//
//
//    public QueryForMongo allowDiskUse(boolean allowDiskUse) {
//
//        meta.setAllowDiskUse(allowDiskUse);
//        return this;
//    }
//
//
//    public QueryForMongo cursorBatchSize(int batchSize) {
//
//        meta.setCursorBatchSize(batchSize);
//        return this;
//    }
//
//
//    public QueryForMongo noCursorTimeout() {
//
//        meta.addFlag(Meta.CursorOption.NO_TIMEOUT);
//        return this;
//    }
//
//    public QueryForMongo exhaust() {
//
//        meta.addFlag(Meta.CursorOption.EXHAUST);
//        return this;
//    }
//
//
//    public QueryForMongo slaveOk() {
//
//        meta.addFlag(Meta.CursorOption.SLAVE_OK);
//        return this;
//    }
//
//    public QueryForMongo allowSecondaryReads() {
//
//        meta.addFlag(Meta.CursorOption.SECONDARY_READS);
//        return this;
//    }
//
//
//    public QueryForMongo partialResults() {
//
//        meta.addFlag(Meta.CursorOption.PARTIAL);
//        return this;
//    }
//
//
//    public Meta getMeta() {
//        return meta;
//    }
//
//
//    public void setMeta(Meta meta) {
//
//        Assert.notNull(meta, "Query meta might be empty but must not be null.");
//        this.meta = meta;
//    }
}
